<?php
namespace Hr\OnlineBundle\Controller;

use Hr\OnlineBundle\Controller\GenericController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContext;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;



// Import new namespaces
use Hr\OnlineBundle\Entity\User;
use Hr\OnlineBundle\Form\UserType;
use Hr\OnlineBundle\Form\UserEditType;
use Hr\OnlineBundle\Form\UserPasswordType;
use Hr\OnlineBundle\Form\ResetUserPasswordType;
use Hr\OnlineBundle\Entity\Document;
use Hr\OnlineBundle\Entity\Application;
use Hr\OnlineBundle\Entity\Token;

use Hr\OnlineBundle\Lib\PasswordStrength;


class UserController extends GenericController
{
    public function registerAction()
    {
		parent::init();

		$user = new User();
		
		$locale = $this->get('session')->get('_locale');
		if ($locale!="en") { 
			// we can try to set the default country from the locale, so if the locale us "de" we assume user country is Germany
			$user->setCountry(strtoupper($locale));
		}

		$form = $this->createForm(new UserType(), $user);
	
		$request = $this->getRequest();
		if ($request->getMethod() == 'POST') {
			 $error =  $this->processRegistrationForm($form, $user);
			 if (!$error) {
				 	// Redirect - This is important to prevent users re-posting
					// the form if they refresh the page
					return $this->redirect($this->generateUrl('hr_online_homepage'));
			 }
		}
        return $this->render('HrOnlineBundle:User:register.html.twig',  array(
				'form' => $form->createView()
		));
    }

	
	public function resetPasswordAction()
    {
		parent::init();

		$request = $this->getRequest();

		$email = $request->request->get('email', $request->query->get('email'));
		$hash = $request->request->get('token', $request->query->get('token'));
		

		$em = $this->getDoctrine()->getManager();
				
		$user = $em->getRepository('HrOnlineBundle:User')->getFindOneByEmail($email);

		$validTokenFound = false;
		if (!is_object($user)) {
			$msg = 'No registered email found: '.$email;
			$this->get('session')->getFlashBag()->add('error', $msg);
		} else {
			$token = $em->getRepository('HrOnlineBundle:Token')->getFindOneByHash($hash);
			if (!is_object($token)) {
				$msg = 'Security token not found!';
				$this->get('session')->getFlashBag()->add('error', $msg);
			} else {
				if ($token->getIsUsed()) {
					$msg = 'This reset password link has already been used. Please request a new one.';
					$this->get('session')->getFlashBag()->add('error', $msg);
				} else if ($token->getExpiresAt()->getTimestamp()<time()) {
					$msg = 'This reset password link has expired. Please request a new one.';
					$this->get('session')->getFlashBag()->add('error', $msg);
				} else {
					$validTokenFound = true;
				}
			}
		}
		
		if ($validTokenFound) {

			$form = $this->createForm(new ResetUserPasswordType(), $user);

			$request = $this->getRequest();
			if ($request->getMethod() == 'POST') {
				
				$error =  $this->processChangePasswordForm($form, $user);
				if (!$error) {
					$token->setIsUsed(1); 
					$token->setUsedAt(new \DateTime()); 
					$em->persist($user);
					$em->flush();
					return $this->redirect($this->generateUrl('hr_online_user_login'));
				}
			
			}
			return $this->render('HrOnlineBundle:User:resetPassword.html.twig',  array(
					'user' => $user,
					'token' => $token->getHash(),
					'form' => $form->createView()
			));

		} else {

			die('not found');
			return $this->redirect($this->generateUrl('hr_online_user_forgotten_password'));
		}
    }


    public function changePasswordAction()
    {
		parent::init();

		$user = $this->get('security.context')->getToken()->getUser();
		
		$originalPassword = $user->getPassword();


		$form = $this->createForm(new UserPasswordType(), $user);

		$request = $this->getRequest();
		if ($request->getMethod() == 'POST') {
			 $error =  $this->processChangePasswordForm($form, $user, $originalPassword);
			 if (!$error) {
				 	// Redirect - This is important to prevent users re-posting
					// the form if they refresh the page
					return $this->redirect($this->generateUrl('hr_online_user_change_password'));
			 }
		}
        return $this->render('HrOnlineBundle:User:changePassword.html.twig',  array(
				'user' => $user,
				'form' => $form->createView()
		));
    }


    public function editAction()
    {
		parent::init();

		$user = $this->get('security.context')->getToken()->getUser();
		
		$form = $this->createForm(new UserEditType(), $user);
	
		$request = $this->getRequest();
		if ($request->getMethod() == 'POST') {
			 $error =  $this->processEditForm($form, $user);
			 if (!$error) {
				 	// Redirect - This is important to prevent users re-posting
					// the form if they refresh the page
					return $this->redirect($this->generateUrl('hr_online_user_edit_profile'));
			 }
		}
        return $this->render('HrOnlineBundle:User:edit.html.twig',  array(
				'form' => $form->createView()
		));
    }



    public function confirmAction()
    {
		parent::init();

		$request = $this->getRequest();
		$email = $request->query->get('email');
		$hash = $request->query->get('token');

		$em = $this->getDoctrine()->getManager();
				
		$user = $em->getRepository('HrOnlineBundle:User')->getFindOneByEmail($email);

		if (!is_object($user)) {
			$msg = 'No registered email found: '.$email;
			$this->get('session')->getFlashBag()->add('error', $msg);
		} else {
			$token = $em->getRepository('HrOnlineBundle:Token')->getFindOneByHash($hash);
			if (!is_object($token)) {
				$msg = 'Security token not found!';
				$this->get('session')->getFlashBag()->add('error', $msg);
			} else {
				$user->setIsEmailVerified(true);
				$em->persist($user);
				$em->flush();
				$msg = 'Email address verified successfully!';
				$this->get('session')->getFlashBag()->add('success', $msg);
			}
		}
        return $this->render('HrOnlineBundle:User:confirm.html.twig',  array(
				'user' => $user
		));
    }


    /**
     * @Route("/login", name="_login")
     * @Template()
     */
    public function loginAction(Request $request)
    {
		parent::init();

        if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            $error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
        } else {
            $error = $request->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
        }

        return array(
            'last_username' => $request->getSession()->get(SecurityContext::LAST_USERNAME),
            'error'         => $error,
        );

    }



    /**
     * @Route("/login_check", name="hr_online_user_login_check")
     */
    public function securityCheckAction()
    {
        // The security layer will intercept this request
    }

    /**
     * @Route("/out", name="hr_online_user_logout")
     */
    public function logoutAction()
    {
        // The security layer will intercept this request
    }

 



    public function loggedAction()
    {
        parent::init();

		$session = $this->getRequest()->getSession();
		if (isset($session)) {
			$lastMarkedPositionId = $session->get('last_marked_position');
			$em = $this->getDoctrine()->getManager();
			$position = $em->getRepository('HrOnlineBundle:Position')->findOneBy(array('id'=>$lastMarkedPositionId));
			if (isset($position)) {
			//	$msg = "You can now apply for this position.";
			//	$this->get('session')->getFlashBag()->add('notice', $msg);
				$session->set('last_marked_position', null);
				$url = $this->generateUrl("hr_online_show_position", array("id" => $position->getId(), "slug" => $position->getSlug()));
				return $this->redirect($url);
			} 
		}
		
		
		$user = $this->get('security.context')->getToken()->getUser();

        return $this->render('HrOnlineBundle:User:logged.html.twig',  array(
				'user' => $user
		));
    }



    public function forgottenPasswordAction(Request $request)
    {
		parent::init();
		
		$request = $this->getRequest();
		if ($request->getMethod() == 'POST') {
			
			$email = $request->request->get('email');
			$em = $this->getDoctrine()->getManager();
			$user = $em->getRepository('HrOnlineBundle:User')->getFindOneByEmail($email);
			

			$token = new Token();
			$token->setUser($user);
			$token->setHash(md5(uniqid($user->getEmail(), true)));
			$numWeeks = $this->container->getParameter('hr_online.user.forgotten_password_token_validity_in_weeks', 2); 
			$expiryDate = \DateTime::createFromFormat('U', strtotime("+".$numWeeks." weeks"));
			$token->setExpiresAt($expiryDate);
			$em->persist($token);
			$em->flush();
					
			$brandName = $this->container->getParameter('hr_online.brand_name'); 
			$message = \Swift_Message::newInstance()
			->setSubject('HROnline Forgotten Password Request')
			->setFrom($this->container->getParameter('hr_online.emails.noreply_email'))
			->setTo($user->getEmail())
			->setBody($this->renderView('HrOnlineBundle:User:forgottenPassword.txt.twig', array('user' => $user, 'token' => $token, 'brandName'=>$brandName, 'numWeeks'=>$numWeeks)));
			$this->get('mailer')->send($message);


			$msg = "A reset password link has been sent to your email.";
			$this->get('session')->getFlashBag()->add('notice', $msg);

			return $this->redirect($this->generateUrl('hr_online_homepage'));

		}

        return $this->render('HrOnlineBundle:User:forgottenPassword.html.twig',  array(
				// 'form' => $form
		));
    }





    public function applyAction(Request $request)
    {
		parent::init();

		$user = $this->get('security.context')->getToken()->getUser();

		$em = $this->getDoctrine()->getManager();
				
		$positionId = $request->request->get('id');

		$position = $em->getRepository('HrOnlineBundle:Position')->findOneBy(array('id'=>$positionId));

		if (isset($position)) {

			$application = $em->getRepository('HrOnlineBundle:Application')->findOneBy(array('user'=>$user, 'position'=>$position));
			if (isset($application)) {
				$msg = "You have already applied for this position.";
				$this->get('session')->getFlashBag()->add('notice', $msg);
			} else {
				$application = new Application();
				$application->setUser($user);
				$application->setPosition($position);
				$em->persist($application);
				$em->flush();
				$msg = "Your application has been successfully sent.";
				$this->get('session')->getFlashBag()->add('success', $msg);
			}

		} else {
			
			$msg = "Position not found.";
			$this->get('session')->getFlashBag()->add('error', $msg);

		}


        return $this->render('HrOnlineBundle:Default:_flashes.html.twig');
    }



	/**
	 * @Template()
	 */
	public function deleteDocumentAction(Request $request)
	{
		$em = $this->getDoctrine()->getEntityManager();
		$id = $request->request->get('id');
		$user = $this->get('security.context')->getToken()->getUser();
		$document = $em->getRepository('HrOnlineBundle:Document')->findOneBy (array('id'=>$id,'user'=>$user));
		$result = 0;
		if (is_object($document)) {
			try {
				$em->remove($document);
			} catch(ContextErrorException $e) {
				// echo $e->getMessage();
			}
			$em->flush();
			$result = 1;
		}
		echo $result;
		exit();
	}

	/**
	 * @Template()
	 */
	public function uploadAction(Request $request)
	{
		parent::init();
		$em = $this->getDoctrine()->getManager();

		$user = $this->get('security.context')->getToken()->getUser();

		 $uploadedDocuments = $user->getDocuments();

		// $uploadedDocuments = $em->getRepository('HrOnlineBundle:Document')->findBy (array('user'=>$user));

		$document = new Document();
		$document->setUser($user);
		$form = $this->createFormBuilder($document)
			->add('name')
			->add('type')
			->add('file')
			->getForm();

		$form->handleRequest($request);

		if ($form->isValid()) {


			$em->persist($document);
			$em->flush();

			$msg = "File uploaded successfully.";
			$this->get('session')->getFlashBag()->add('notice', $msg);

			return $this->redirect($this->generateUrl('hr_online_user_upload'));
		}

		return array('form' => $form->createView(), 'documents'=>$uploadedDocuments);
	}


	protected function checkPassword($password,  $user, $originalEncryptedPassword = null) {
			$encoder = $this->getEncoder($user);

			$originalEncryptedPassword = $originalEncryptedPassword ? $originalEncryptedPassword : $user->getPassword() ;
			
			return $encoder->encodePassword($password, $user->getSalt()) == $originalEncryptedPassword  ;
	}




	protected function processChangePasswordForm($form, $user, $originalPassword=null) {
			
			$request = $this->getRequest();

			$form->bind($request);

			$error = true;

			if ($form->isValid()) {

				$em = $this->getDoctrine()->getManager();
				
				if ($originalPassword && !$this->checkPassword($user->getOldPassword(), $user, $originalPassword)) {

					$msg = 'Old password is incorrect!';
					$this->get('session')->getFlashBag()->add('error', $msg);

				} elseif ($user->getPassword()!=$user->getRepeatPassword()) {

					$msg = 'Passwords do not match!';
					$this->get('session')->getFlashBag()->add('error', $msg);

				} else {
					
					$this->encodeUserPassword($user);

					// Persist the user and token entities (save to the database)				
					$em->persist($user);
					$em->flush();

					$msg = "Password changed successfully.";
					$this->get('session')->getFlashBag()->add('success', $msg);

					$error = false;

				}
			}
			return $error;
	}



	protected function encodeUserPassword($user) {
			$encoder = $this->getEncoder($user);
			$user->setPassword($encoder->encodePassword($user->getPassword(), $user->getSalt()));
	}


	protected function processRegistrationForm($form, $user) {
			
			$request = $this->getRequest();

			$form->bind($request);

			$error = true;

			if ($form->isValid()) {

				$em = $this->getDoctrine()->getManager();
				
				$existingUser = $em->getRepository('HrOnlineBundle:User')->getFindOneByEmail($user->getEmail());

				if (is_object($existingUser)) {

					$msg = $this->get('translator')->trans('A user with the specified email already exists!');
					$this->get('session')->getFlashBag()->add('error', $msg);

				} elseif ($user->getPassword()!=$user->getRepeatPassword()) {

					$msg = 'Passwords do not match!';
					$this->get('session')->getFlashBag()->add('error', $msg);

				} else {
					
					// Persist the user and token entities (save to the database)
				
					$token = new Token();
					$token->setUser($user);
					$token->setHash(md5(uniqid($user->getEmail(), true)));
					$numWeeks = $this->container->getParameter('hr_online.user.registration_token_validity_in_weeks'); 
					$expiryDate = \DateTime::createFromFormat('U', strtotime("+".$numWeeks." weeks"));
					$token->setExpiresAt($expiryDate);
					
					$this->encodeUserPassword($user);

					$em->persist($user);
					$em->persist($token);

					$this->uploadUserDocuments($user);

					$em->flush();
					
					$brandName = $this->container->getParameter('hr_online.brand_name'); 
					$message = \Swift_Message::newInstance()
					->setSubject('HROnline Email Verification')
					->setFrom($this->container->getParameter('hr_online.emails.noreply_email'))
					->setTo($user->getEmail())
					->setBody($this->renderView('HrOnlineBundle:User:register.txt.twig', array('user' => $user, 'token' => $token, 'brandName'=>$brandName)));
					$this->get('mailer')->send($message);

					$msg = "An email verification link has been sent to your email.";
					$this->get('session')->getFlashBag()->add('notice', $msg);

					$error = false;

				}
			}
			return $error;
	}

	protected function uploadUserDocuments($user) {
		if ($file = $user->getCv()) {
			$this->uploadUserDocument($user, 'cv', $file);
		}
		if ($file = $user->getReference()) {
			$this->uploadUserDocument($user, 'reference', $file);
		}
		if ($file = $user->getLetter()) {
			$this->uploadUserDocument($user, 'letter', $file);
		}
	}


	protected function uploadUserDocument($user, $type, $uploadedFile) {

		$em = $this->getDoctrine()->getManager();

		$document = new Document();
		$document->setUser($user);
		$document->setFile($uploadedFile);
		$document->setName($uploadedFile->getClientOriginalName());
		$document->setType($type);

		$em->persist($document);

	}


	protected function processEditForm($form, $user) {
			
			$request = $this->getRequest();

			$form->bind($request);

			$error = true;

			if ($form->isValid()) {

				$em = $this->getDoctrine()->getManager();
				$em->persist($user);
				$this->uploadUserDocuments($user);
				$em->flush();
				$msg = 'Information saved successfully!';
				$this->get('session')->getFlashBag()->add('success', $msg);

			}
			return $error;
	}

	protected function getEncoder($user) {
		 return $this->container->get('security.encoder_factory')->getEncoder($user);
	}

	public function checkPasswordAction(Request $request)
	{
		 $user = $this->get('security.context')->getToken()->getUser();
		 $password = $request->request->get('password');
		 $encoder = $this->getEncoder($user);
		 $encryptedPass = $encoder->encodePassword($password, $user->getSalt());
		 $correct = $user->getPassword() == $encryptedPass ? 1 : 0 ;

		 if ($correct) {
			$msg = "Old password is correct.";
			$this->get('session')->getFlashBag()->add('success', $msg);
		} else {
			$msg = "Old password is incorrect!";
			$this->get('session')->getFlashBag()->add('error', $msg);
		}

        return $this->render('HrOnlineBundle:Default:_flashes.html.twig', array('plain'=>true));
	}



	public function calculatePasswordStrengthAction(Request $request)
	{
		  $strength = PasswordStrength::calculate(
                $request->request->get('password'),
                $request->request->get('email')
		  );
		  echo PasswordStrength::getBar($strength);
		  return exit();
	}






}